package com.example.demo.service.impl;
import com.example.demo.entity.Banner;
import com.example.demo.entity.Category;
import com.example.demo.entity.Goods;
import com.example.demo.entity.GoodsSkus;
import com.example.demo.entity.GoodsSkusCombinations;
import com.example.demo.entity.GoodsSkusValue;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ErrorCode;
import com.example.demo.mapper.BannerMapper;
import com.example.demo.mapper.CategoryMapper;
import com.example.demo.mapper.GoodsMapper;
import com.example.demo.mapper.GoodsSkusMapper;
import com.example.demo.mapper.GoodsSkusValueMapper;
import com.example.demo.service.GoodsService;
import com.example.demo.service.GoodsSkusService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.lang.reflect.Field;

@Service
public class GoodsServiceImpl implements GoodsService {
    private static final Logger logger = LoggerFactory.getLogger(GoodsServiceImpl.class);

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BannerMapper bannerMapper;

    @Autowired
    private GoodsSkusService goodsSkusService;

    @Autowired
    private GoodsSkusMapper goodsSkusMapper;

    @Autowired
    private GoodsSkusValueMapper goodsSkusValueMapper;

    @Autowired
    private GoodsSkusCombinationsServiceImpl goodsSkusCombinationsService;

    @Override
    public Goods createGoods(Goods goods) {
        if (goodsMapper.countByTitle(goods.getTitle()) > 0) {
            throw new BusinessException(ErrorCode.GOODS_EXISTS, "商品已存在");
        }
        
        goodsMapper.insert(goods);
        logger.info("Created goods with id: {}", goods.getId());
        return goods;
    }

    @Override
    public boolean updateGoods(Goods goods) {
        Goods existing = goodsMapper.selectById(goods.getId());
        if (existing == null) {
            throw new BusinessException(ErrorCode.GOODS_NOT_FOUND, "商品不存在");
        }

        // 使用反射遍历goods对象的属性
        try {
            for (Field field : goods.getClass().getDeclaredFields()) {
                field.setAccessible(true); // 允许访问私有字段
                Object value = field.get(goods); // 获取字段值
                if (value != null) { // 检查字段值是否为空
                    Field existingField = existing.getClass().getDeclaredField(field.getName());
                    existingField.setAccessible(true);
                    existingField.set(existing, value); // 将非空字段值复制到existing对象中
                }
            }
        } catch (Exception e) {
            logger.error("反射操作出错", e);
            throw new RuntimeException("更新商品信息时出错", e);
        }

        int result = goodsMapper.updateById(existing);
        logger.info("Updated goods with id: {}", goods.getId());
        return result > 0;
    }

    @Override
    public int changeStatus(List<Integer> ids, Integer status) {
        int result = goodsMapper.updateStatusByIds(ids, status);
        logger.info("Changed status for {} goods to {}", result, status);
        return result;
    }

    @Override
    public Map<String, Object> getGoodsPage(Integer page, Integer limit, String title, Integer category_id, Integer status, Boolean onlyShowStockWarning) {
        // 获取 categories list
        List<Category> categories = categoryMapper.getCategoryList("", null);

        PageHelper.startPage(page, limit);
        List<Goods> goodsList = goodsMapper.selectPage(title, category_id, status, onlyShowStockWarning);
        for(int i = 0 ; i < goodsList.size() ; i++) {
            Goods mygoods = goodsList.get(i);
            List<Banner> banners = bannerMapper.selectBannersByGoodsId(mygoods.getId());
            mygoods.setBanners(banners);
        }

         // Get total count
        PageInfo<Goods> pageInfo = new PageInfo<>(goodsList);
        
        // Build result map
        Map<String, Object> result = new HashMap<>();
        result.put("list", goodsList);
        result.put("totalCount", pageInfo.getTotal());
        result.put("categories", categories);
        logger.info("Fetched {} coupons on page {}", goodsList.size(), page);
        return result;
    }

    @Override
    public int deleteGoods(List<Integer> ids) {
        int result = goodsMapper.deleteByIds(ids);
        logger.info("Deleted {} goods", result);
        return result;
    }

    @Override
    public Goods getGoodsById(Integer id) {
        Goods goods = goodsMapper.selectById(id);
    
        if (goods == null) {
            throw new BusinessException(ErrorCode.GOODS_NOT_FOUND, "商品不存在");
        }
        logger.info("Fetched goods with id: {}", id);
        return goods;
    }

    /**
     * 根据商品ID获取商品详情
     *
     * @param id 商品ID
     * @return 商品详情对象
     */
    @Override
    public Goods getGoodsDetailById(Integer id) {
        Goods goods = getGoodsById(id);
        if (goods == null) {
            throw new BusinessException(ErrorCode.GOODS_NOT_FOUND, "商品不存在");
        }
        List<Banner> banners = bannerMapper.selectBannersByGoodsId(id);
        List<GoodsSkus> skus = goodsSkusService.getGoodsSkusWithValuesByGoodsId(id);
        List<GoodsSkusCombinations> combinations = goodsSkusCombinationsService.getGoodsSkuCombinationsByGoodsId(id);
        if(goods != null) {
            goods.setBanners(banners);
            goods.setSkus(skus);
            goods.setCombinations(combinations);
        }
        logger.info("Fetched goods detail with id: {}", id);
        return goods;
    }

    @Transactional
    @Override
    public Boolean setGoodsSkusAndCombinationsById(Integer id, Goods goods) {
        // 1. 更新 goods 表
        goods.setId(id);
        goodsMapper.updateById(goods);

        // 2. 处理 goods_skus 表
        List<GoodsSkus> incomingSkus = goods.getSkus();
        List<GoodsSkus> existingSkus = goodsSkusMapper.selectByGoodsId(id);

        // 更新或新增 skus
        for (GoodsSkus incomingSku : incomingSkus) {
            incomingSku.setGoods_id(id);
            if (incomingSku.getId() != null && existingSkus.stream().anyMatch(s -> s.getId().equals(incomingSku.getId()))) {
                goodsSkusMapper.updateById(incomingSku);
            } else {
                goodsSkusMapper.insert(incomingSku);
            }
        }

        // 删除多余的 skus
        for (GoodsSkus existingSku : existingSkus) {
            if (incomingSkus.stream().noneMatch(s -> s.getId().equals(existingSku.getId()))) {
                goodsSkusMapper.deleteById(existingSku.getId());
            }
        }

        // 3. 处理 goods_skus_value 表
        for (GoodsSkus incomingSku : incomingSkus) {
            List<GoodsSkusValue> incomingValues = incomingSku.getGoodsSkusValues();
            List<GoodsSkusValue> existingValues = goodsSkusValueMapper.selectBySkuId(incomingSku.getId());

            // 更新或新增 values
            for (GoodsSkusValue incomingValue : incomingValues) {
                incomingValue.setSku_id(incomingSku.getId());
                if (incomingValue.getId() != null && existingValues.stream().anyMatch(v -> v.getId().equals(incomingValue.getId()))) {
                    goodsSkusValueMapper.updateById(incomingValue);
                } else {
                    goodsSkusValueMapper.insert(incomingValue);
                }
            }

            // 删除多余的 values
            for (GoodsSkusValue existingValue : existingValues) {
                if (incomingValues.stream().noneMatch(v -> v.getId().equals(existingValue.getId()))) {
                    goodsSkusValueMapper.deleteById(existingValue.getId());
                }
            }
        }

        // 4. 处理商品规格调整后的Combinations
        goodsSkusCombinationsService.setGoodsSkuCombinationsByGoodsId(id);

        return true;
    }

    @Override
    @Transactional
    public Boolean setCombinationsDataById(Integer id, List<GoodsSkusCombinations> combs) {
        for (GoodsSkusCombinations comb : combs) {
            goodsSkusCombinationsService.updateGoodsSkuCombinations(comb);
        }
        return true;
    }
}
